package com.example.jigsawpuzzles.slice;

import java.io.FileDescriptor;
import java.util.ArrayList;
import java.util.Collections;

import com.example.jigsawpuzzles.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.ability.DataAbilityHelper;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Image;
import ohos.agp.components.TableLayout;
import ohos.agp.components.TickTimer;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Texture;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.window.dialog.ToastDialog;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.ImageInfo;
import ohos.media.image.common.Rect;
import ohos.media.image.common.Size;
import ohos.media.photokit.metadata.AVStorage;
import ohos.utils.net.Uri;


public class jigsawSlice extends AbilitySlice {

    int spacex;
    int spacey;
    int gameSize = 1080;
    int Num = 2;
    TableLayout tableLayout;
    Image[][] images;
    PixelMap pixelMap;
    TickTimer tickTimer;
    PixelMap[][] pixelMapsRaw;
    PixelMap[][] pixelMapsPlay;
    int staticImageNum = 6;
    int[] staticImages;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_jigsaw);
        loadImg();
        Num = intent.getIntParam("selectDiff", 0) + 3;
        int selectImg = intent.getIntParam("selectImg", 0);
        // 初始化参数
        initParams();

        // 设置三个按钮的点击事件
        setClickedListener();

        // 定时器模块
        tickTimer = (TickTimer) findComponentById(ResourceTable.Id_my_tt);
        tickTimer.start();

        // 初始化组件
        images[0][0] = new Image(getContext());

        // -1：用户上传的图片
        if (selectImg == -1) {
            images[0][0].setPixelMap(getUploadImg(intent.getStringParam("pixelMap")));
        }
        // 其他数值：图片资源的编号
        else {
            images[0][0].setPixelMap(staticImages[selectImg]);
        }

        // 裁切并打乱
        pixelMap = images[0][0].getPixelMap();
        pixelMapsRaw = cutPic(pixelMap);
        pixelMapsPlay = shuffle(pixelMapsRaw);

        for (int i = 0; i < Num; i++) {
            for (int j = 0; j < Num; j++) {
                initImages(i, j);
                int finalI = i;
                int finalJ = j;
                images[i][j].setClickedListener(component -> {
                    // 如果选中的是空格旁边的
                    if (clickBesideSpace(finalI, finalJ)) {
                        // 移动图片
                        moveImage(finalI, finalJ);

                        // 判断游戏是否结束
                        if (gameOver()) {
                            makeToast("恭喜你，挑战成功");
                            tickTimer.stop();
                        }
                    }
                });
            }
        }
    }

    // 加载预先指定的图片
    private void loadImg() {
        // 初始化图片库
        staticImages = new int[staticImageNum];

        // 加载静态图片资源
        staticImages[0] = ResourceTable.Media_111;
        staticImages[1] = ResourceTable.Media_c;
        staticImages[2] = ResourceTable.Media_cd;
        staticImages[3] = ResourceTable.Media_cs;
        staticImages[4] = ResourceTable.Media_e;
        staticImages[5] = ResourceTable.Media_icon;

    }

    // 重新设置图片顺序
    private void setImage(PixelMap[][] pixelMapsPlay) {
        for (int i = 0; i < Num; i++) {
            for (int j = 0; j < Num; j++) {
                try {
                    images[i][j].setPixelMap(pixelMapsPlay[i][j]);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 获取用户上传的图片
    private PixelMap getUploadImg(String chooseImgUri) {

        //定义数据能力帮助对象
        DataAbilityHelper helper = DataAbilityHelper.creator(getContext());

        //定义图片来源对象
        ImageSource imageSource = null;

        //获取选择的Img对应的Id
        String chooseImgId = null;

        //判断是选择了文件还是图库
        if (chooseImgUri.lastIndexOf("%3A") != -1) {
            chooseImgId = chooseImgUri.substring(chooseImgUri.lastIndexOf("%3A") + 3);
        } else {
            chooseImgId = chooseImgUri.substring(chooseImgUri.lastIndexOf('/') + 1);
        }

        //获取图片对应的uri，由于获取到的前缀是content，我们替换成对应的dataAbility前缀
        Uri uri = Uri.appendEncodedPathToUri(AVStorage.Images.Media.EXTERNAL_DATA_ABILITY_URI, chooseImgId);
        try {
            //读取图片
            FileDescriptor fd = helper.openFile(uri, "r");
            imageSource = ImageSource.create(fd, null);

            //创建位图
            PixelMap pixelMap = imageSource.createPixelmap(null);

            return pixelMap;

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (imageSource != null) {
                // 释放资源
                imageSource.release();
            }
        }
    }

    // 设置三个按钮的点击事件
    private void setClickedListener() {
        // 重新打乱按钮
        findComponentById(ResourceTable.Id_shuffle).setClickedListener(component -> {
            // 打乱
            pixelMapsPlay = shuffle(pixelMapsRaw);

            // 设置图片资源
            setImage(pixelMapsPlay);

            // 重新设置空格位置
            spacex = Num - 1;
            spacey = Num - 1;
        });

        // 查看答案按钮
        findComponentById(ResourceTable.Id_answer).setClickedListener(component -> {
            // 设置为正确答案
            setImage(pixelMapsRaw);
            for (int m = 0; m < Num; m++) {
                for (int x = 0; x < Num; x++) {
                    pixelMapsPlay[m][x] = pixelMapsRaw[m][x];
                }
            }

            // 重新设置空格位置
            spacex = Num - 1;
            spacey = Num - 1;

            // 停止计时
            tickTimer.stop();
        });

        // 返回主界面按钮
        findComponentById(ResourceTable.Id_returnMain).setClickedListener(component -> {
            terminate();
        });
    }

    private void initImages(int i, int j) {
        images[i][j] = new Image(getContext());
        images[i][j].setHeight(gameSize / Num);
        images[i][j].setWidth(gameSize / Num);
        images[i][j].setPixelMap(pixelMapsPlay[i][j]);
        images[i][j].setMarginTop(10);
        images[i][j].setMarginLeft(10);
        tableLayout.addComponent(images[i][j]);
    }

    private void moveImage(int x, int y) {
        images[spacex][spacey].setPixelMap(pixelMapsPlay[x][y]);
        images[x][y].setPixelMap(null);
        pixelMapsPlay[spacex][spacey] = pixelMapsPlay[x][y];
        pixelMapsPlay[x][y] = null;
        spacex = x;
        spacey = y;
    }

    private boolean clickBesideSpace(int x, int y) {
        return (x == spacex && Math.abs(y - spacey) == 1) || (y == spacey && Math.abs(x - spacex) == 1);
    }

    private boolean gameOver() {
        boolean over = true;
        for (int m = 0; m < Num; m++) {
            for (int x = 0; x < Num; x++) {
                try {
                    over = over & pixelMapsRaw[m][x].equals(pixelMapsPlay[m][x]);
                } catch (NullPointerException e) {
                    e.printStackTrace();
                }
            }
        }
        return over;
    }

    private void initParams() {
        tableLayout = (TableLayout) findComponentById(ResourceTable.Id_tableLayout);
        images = new Image[Num][Num];
        spacex = Num - 1;
        spacey = Num - 1;
        tableLayout.setColumnCount(Num);
        tableLayout.setRowCount(Num);
    }

    PixelMap[][] cutPic(PixelMap pixelMap) {
        ImageInfo imageInfo = pixelMap.getImageInfo();
        int width = imageInfo.size.width;
        int height = imageInfo.size.height;
        int size = Math.min(width, height);
        int singleSize = size / Num;

        PixelMap.InitializationOptions options = new PixelMap.InitializationOptions();
        options.pixelFormat = imageInfo.pixelFormat;
        options.editable = true;
        options.size = new Size(gameSize / Num, gameSize / Num);

        PixelMap[][] pixelMaps = new PixelMap[Num][Num];
        for (int i = 0; i < Num; i++) {
            for (int j = 0; j < Num; j++) {
                pixelMaps[i][j] = PixelMap.create(pixelMap, new Rect(i * singleSize, j * singleSize, singleSize, singleSize), options);
                Canvas canvas = new Canvas(new Texture(pixelMaps[i][j]));
                Paint paint = new Paint();
                paint.setTextSize(gameSize / Num * 2);
                paint.setColor(Color.BLACK);
                canvas.drawText(paint, "" + i * Num + j + 1, gameSize / Num, gameSize / Num * 2);
            }
        }
        pixelMaps[Num - 1][Num - 1] = null;
        return pixelMaps;
    }

    PixelMap[][] shuffle(final PixelMap[][] pixelMaps) {
        ArrayList<PixelMap> arrayList = new ArrayList<>();
        for (int i = 0; i < Num; i++) {
            for (int j = 0; j < Num; j++) {
                if (i != Num - 1 || j != Num - 1) {
                    arrayList.add(pixelMaps[i][j]);
                }
            }
        }
        Collections.shuffle(arrayList);
        arrayList.add(null);

        PixelMap[][] pixelMapsNew = new PixelMap[Num][Num];

        for (int i = 0; i < Num; i++) {
            for (int j = 0; j < Num; j++) {
                pixelMapsNew[i][j] = arrayList.get(i * Num + j);
            }
        }
        return pixelMapsNew;
    }

    void makeToast(String msg) {
        ToastDialog td = new ToastDialog(this);
        td.setText(msg);
        td.setAlignment(LayoutAlignment.CENTER);
        td.setDuration(1000);
        td.show();
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }
}
